package com.goldman.aplt.util;

import com.goldman.oss.common.FileStorageProcessorFactory;
import com.goldman.oss.common.internal.pojo.UploadFileInfo;
import com.opencsv.CSVWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.opencsv.CSVReader;

/**
 * @description：导出excel工具类
 * @author： chenxiangxiang
 * @create： 2024/2/23 14:23
 */
@Component
@Slf4j
public class ExcelUtil {

    public static String LOCAL_PATH = "/data/file/temp/";
    public static String REMOTE_PATH = "goldman/app/report/bill/";


    public List<List<String>> csvParse(MultipartFile file) throws Exception {
        List<List<String>> datas = new ArrayList<>();

        try (InputStreamReader reader = new InputStreamReader(file.getInputStream(), "UTF-8");
             CSVReader csvReader = new CSVReader(reader)) {

            boolean isHead = true;
            String[] nextLine;
            while ((nextLine = csvReader.readNext()) != null) {
                // 处理每一行数据
                // nextLine 是一个包含CSV文件中当前行所有字段的字符串数组
                // 例如: System.out.println(Arrays.toString(nextLine));
                // 在这里，你可以将解析的数据存储到数据库或进行其他处理
                if (isHead) {
                    isHead = false;
                    continue;
                }
                datas.add(Arrays.asList(nextLine));

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datas;
    }

    public String csvSave(String[] header, List<String[]> data, String fileNmae) {
        log.info("csvSave start");
        String localFullName = LOCAL_PATH + fileNmae;
        File folds = new File(LOCAL_PATH);
        if (!folds.exists()) {
            folds.mkdirs();
        }

        File file = null;
        try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(localFullName));
             CSVWriter writer = new CSVWriter(bufferedWriter)) {

            writer.writeNext(header);

            int i = 1;
            for (String[] row : data) {
                log.info("csvSave doing : " + i);
                i++;
                writer.writeNext(row);
            }

            writer.flush();

            file = new File(localFullName);
            UploadFileInfo uploadFileInfo = FileStorageProcessorFactory.ofUpload(file)
                    .setPath(REMOTE_PATH)
                    .setFilename(fileNmae)
                    .setBusinessCode("obs-goldman-biz")
                    .uploadFile();

            return uploadFileInfo.getObjectKey();
        } catch (IOException e) {
            log.error("csv err", e);
        } finally {
            if (CommUtil.isNotNull(file)) {
                //file.delete();
            }
        }

        log.info("csvSave end");
        return "";
    }

    public ByteArrayOutputStream csvExport(String[] header, List<String[]> data) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        try ( // 这里我们指定字符集为 UTF-8
              OutputStreamWriter writerStream = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);) {

            // 使用 OutputStreamWriter 创建 CSVWriter
            CSVWriter csvWriter = new CSVWriter(writerStream);

            csvWriter.writeNext(header);

            for (String[] row : data) {
                csvWriter.writeNext(row);
            }

            csvWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return outputStream;

    }


    public String saveExcel(List<String> header, List<List<String>> data, String fileNmae) {
        File folds = new File(LOCAL_PATH);
        if (!folds.exists()) {
            folds.mkdirs();
        }

        String localFullName = LOCAL_PATH + fileNmae;

        File file = new File(localFullName);

        try (Workbook workbook = new XSSFWorkbook();
             FileOutputStream outputStream = new FileOutputStream(localFullName)) {

            buildWorkBook(workbook, header, data);

            workbook.write(outputStream);

            UploadFileInfo uploadFileInfo = FileStorageProcessorFactory.ofUpload(file)
                    .setPath(REMOTE_PATH)
                    .setFilename(fileNmae)
                    .setBusinessCode("obs-goldman-biz")
                    .uploadFile();

            return uploadFileInfo.getObjectKey();
        } catch (IOException e) {
            log.error("saveExcel error = ", e);
        } finally {
            file.delete();
        }
        return "";
    }


    /**
     * 导出excel
     *
     * @param header
     * @param data
     * @return
     */
    public ByteArrayOutputStream exportExcel(List<String> header, List<List<String>> data) {
        try (Workbook workbook = new XSSFWorkbook();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

            buildWorkBook(workbook, header, data);

            workbook.write(outputStream);

            return outputStream;
        } catch (IOException e) {
            log.error("", e);
        }

        return null;
    }

    private void buildWorkBook(Workbook workbook, List<String> header, List<List<String>> data) {
        Sheet sheet = workbook.createSheet("Sheet1");
        // 创建表头
        Row headerRow = sheet.createRow(0);
        for (int i = 0; i < header.size(); i++) {
            headerRow.createCell(i).setCellValue(header.get(i));
        }

        // 填充数据
        for (int i = 0; i < data.size(); i++) {
            Row dataRow = sheet.createRow(i + 1);
            List<String> rowData = data.get(i);
            for (int j = 0; j < rowData.size(); j++) {
                dataRow.createCell(j).setCellValue(rowData.get(j));
            }
        }
    }


    /**
     * 解析excel文件
     *
     * @param file
     */
    public List<List<String>> parseExcelFile(MultipartFile file, int headCloumnNum) throws Exception {
        List<List<String>> datas = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = WorkbookFactory.create(inputStream);
        ) {
            Sheet sheet = workbook.getSheetAt(0);

            //头行
            List<String> headList = new ArrayList<>();
            //非头行
            List<String> bodyList = null;

            boolean isHead = true;
            for (Row row : sheet) {
                if (isHead) {
                    addRow(headList, row);
                    isHead = false;
                    continue;
                }

                bodyList = new ArrayList<>();
                addRow(bodyList, row);

                //补齐空数据
                if (bodyList.size() < headList.size()) {
                    for (int i = 0; i < headList.size() - bodyList.size(); i++) {
                        bodyList.add("");
                    }
                }

                datas.add(bodyList);
            }

            if (headList.size() != headCloumnNum) {
                throw new Exception("excel column is not correct");
            }
        } catch (Exception e) {
            throw e;
        }

        return datas;
    }

    public void addRow(List<String> rowData, Row row) {
        for (Cell cell : row) {
            if (cell.getCellType() != CellType.STRING) {
                cell.setCellType(CellType.STRING);
            }
            rowData.add(cell.getStringCellValue());
        }
    }
}
